iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Modern Web

現在就學React.js 系列 第 20

在 React 中使用 Axios 進行非同步請求 - Day20

  • 分享至 

  • xImage
  •  

在網頁中常常需要與後端進行資料的溝通,通常是使用API來獲取、修改、或刪除資料。在這篇文章中,要學習如何在 React 中使用 Axios 套件來進行 CRUD 操作(Create、Read、Update、Delete)。為了簡化學習過程,我們將使用一個模擬的 API——JSONPlaceholder 作為練習平台。

什麼是 CRUD?

CRUD 代表四種基本的資料操作方式:

  • Create(新增資料):用來在伺服器端新增一筆新的資料。
  • Read(讀取資料):用來從伺服器端獲取現有的資料。
  • Update(更新資料):用來修改伺服器端現有的資料。
  • Delete(刪除資料):用來刪除伺服器端現有的資料。

為什麼使用 Axios?

Axios 是一個基於 Promise 的 HTTP 請求庫,與原生的 fetch API 相比,它提供了更豐富的功能,如自動轉換 JSON、攔截請求和響應、處理錯誤等強大功能。學會用它真的非常方便與實用!

首先安裝Axios


npm install axios

接著在 React 應用中引入 Axios:

import axios from 'axios';

接下來,將介紹如何實作 CRUD 操作。

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState([]);
  const [error, setError] = useState(null);

  // 使用 useEffect 來執行初始的 GET 請求
  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      setData(response.data);
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div>
      <h1>JSONPlaceholder Data</h1>
      {error && <p style={{ color: 'red' }}>{error}</p>}
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

  • useEffect:使用 useEffect 在組件首次渲染後執行 fetchData 函式,來發送 GET 請求並獲取資料。
  • axios.get:發送 GET 請求到 JSONPlaceholder,並將回傳的資料存到 data 狀態中。
  • 錯誤處理:如果請求失敗,我們會將錯誤訊息儲存到 error,並在畫面上顯示錯誤訊息。

當畫面初始後,就會透過useEffect執行fetchData函式,並發送GET請求後拿取到後,畫面上會顯示從 API 獲取的資料列表。

https://jsonplaceholder.typicode.com/posts 的資料有一百筆,如下:

[
    {
        "userId": 1,
        "id": 1,
        "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    },
    {
        "userId": 1,
        "id": 2,
        "title": "qui est esse",
        "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
    },
    {
        "userId": 1,
        "id": 3,
        "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
        "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
    },
    {
        "userId": 1,
        "id": 4,
        "title": "eum et est occaecati",
        "body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit"
    },
   
   // ... 略
   
]

實作 CRUD 操作

1. Create (POST 請求)

我們將新增一個表單,讓使用者可以輸入資料並提交。使用者的輸入會透過 POST 請求傳送到伺服器。

const createPost = async (newPost) => {
  try {
    const response = await axios.post('https://jsonplaceholder.typicode.com/posts', newPost);
    setData([...data, response.data]); // 更新資料狀態,新增新的項目
  } catch (err) {
    setError(err.message);
  }
};

return (
  <form onSubmit={(e) => {
    e.preventDefault();
    createPost({ title: 'New Post', body: 'This is a new post', userId: 1 });
  }}>
    <button type="submit">Add Post</button>
  </form>
);

2. Read (GET 請求)

這已經在我們的 fetchData 函式中實現了,當頁面載入時會自動取得資料。

3. Update (PUT 請求)

要更新伺服器上的資料,我們可以使用 axios.putaxios.patch 來更新現有的項目。


const updatePost = async (id, updatedPost) => {
  try {
    const response = await axios.put(`https://jsonplaceholder.typicode.com/posts/${id}`, updatedPost);
    const updatedData = data.map(post => (post.id === id ? response.data : post));
    setData(updatedData);
  } catch (err) {
    setError(err.message);
  }
};

4. Delete (DELETE 請求)

刪除資料的操作可以使用 axios.delete 來完成:


const deletePost = async (id) => {
  try {
    await axios.delete(`https://jsonplaceholder.typicode.com/posts/${id}`);
    setData(data.filter(post => post.id !== id));
  } catch (err) {
    setError(err.message);
  }
};

結合 CRUD 到應用程式中

以下是完整範例,將 CRUD 操作結合在一個應用程式中:


import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState([]);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      setData(response.data);
    } catch (err) {
      setError(err.message);
    }
  };

  const createPost = async (newPost) => {
    try {
      const response = await axios.post('https://jsonplaceholder.typicode.com/posts', newPost);
      setData([...data, response.data]);
    } catch (err) {
      setError(err.message);
    }
  };

  const updatePost = async (id, updatedPost) => {
    try {
      const response = await axios.put(`https://jsonplaceholder.typicode.com/posts/${id}`, updatedPost);
      const updatedData = data.map(post => (post.id === id ? response.data : post));
      setData(updatedData);
    } catch (err) {
      setError(err.message);
    }
  };

  const deletePost = async (id) => {
    try {
      await axios.delete(`https://jsonplaceholder.typicode.com/posts/${id}`);
      setData(data.filter(post => post.id !== id));
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div>
      <h1>CRUD with JSONPlaceholder</h1>
      {error && <p style={{ color: 'red' }}>{error}</p>}
      <form onSubmit={(e) => {
        e.preventDefault();
        createPost({ title: 'New Post', body: 'This is a new post', userId: 1 });
      }}>
        <button type="submit">Add Post</button>
      </form>
      <ul>
        {data.map(item => (
          <li key={item.id}>
            {item.title}
            <button onClick={() => updatePost(item.id, { title: 'Updated Title', body: 'Updated body', userId: 1 })}>
              Update
            </button>
            <button onClick={() => deletePost(item.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

總結

這篇文章主要是練習在 React 中執行非同步請求,並用到昨日學習的 useEffect 在組件渲染後進行 API 請求,最後運用 Axios 來實現 CRUD 操作的練習。

後記

本文將會同步更新到我的部落格

黃禎平 – Medium


上一篇
React中處理副作用的利器 - useEffect - Day19
下一篇
告別不必要的渲染:理解 React useRef -Day21
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言